/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.arg.deploy.webapp.tag.hotfix.ctrl;

import com.arg.deploy.bean.Tag;
import com.arg.deploy.bean.User;
import com.arg.deploy.common.FileUtil;
import com.arg.deploy.common.GenScript;
import com.arg.deploy.common.GenerateScriptUtil;
import com.arg.deploy.common.ProcessUbuntu;
import com.arg.deploy.common.TextFileReaderUtil;
import com.arg.deploy.webapp.attribute.FileAttribute;
import com.arg.deploy.webapp.common.ComboboxUtil;
import com.arg.deploy.webapp.common.ImportFileReaderUtil;
import com.arg.deploy.webapp.common.MainPageController;
import com.arg.deploy.webapp.popup.ctrl.PopupCtrl;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.zkoss.util.media.Media;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.UploadEvent;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Div;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Label;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Radiogroup;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.Window;

/**
 *
 * @author sorasaks
 */
public class TagHotfixMainCtrl extends MainPageController {

    private static final Logger LOG = Logger.getLogger(TagHotfixMainCtrl.class);
    private static final String FROM_POPUP_TEMPLATE = "/WEB-INF/layouts/defaults/popup/popup.zul";
    private Label mainLabel;
    private Radiogroup rdoType;
    private Checkbox chkAll;
    private Combobox cbbPath;
    private Combobox cbbTagName;
    private Combobox cbbHeader;
    private Combobox cbbCVSName;
    private Combobox cbbLastedTagName;
    private Div divError;
    private Grid gridTagNormal;
    private Grid gridErrorTag;
    private Grid gridDiffTag;
    private Button btnUpload;
    private Button btnReaddingFile;
    private Button btnGenerate;
    private List<String> path = new ArrayList<String>();
    private List<String> tagName = new ArrayList<String>();
    private List<String> header = new ArrayList<String>();
    private List<String> cvsName = new ArrayList<String>();
    private List<String> lastedTagName = new ArrayList<String>();
    private TagHotfixNormalMainRenderer normalRender;
    private TagHotfixDiffMainRenderer diffRender;
    private TagHotfixErrorMainRenderer errorRender;
    private Label lbTotalNormal;
    private Label lbTotalDifference;
    private Label lbTotalError;

    public TagHotfixMainCtrl() {
        super("Deploy :: CVS Tag", Boolean.FALSE);
    }

    @Override
    public void doAfterCompose(Component comp) throws Exception {
        super.doAfterCompose(comp); //To change body of generated methods, choose Tools | Templates.
        initialComponent();
        initialCombobox();
        initialRenderer();
        initialEventListener();
    }

    private void initialRenderer() {
        normalRender = new TagHotfixNormalMainRenderer(chkAll);
        diffRender = new TagHotfixDiffMainRenderer();
        errorRender = new TagHotfixErrorMainRenderer();
        gridTagNormal.setRowRenderer(normalRender);
        gridDiffTag.setRowRenderer(diffRender);
        gridErrorTag.setRowRenderer(errorRender);
    }

    private void initialComponent() {
        mainLabel.setValue("Upload");
        rdoType.setSelectedIndex(0);
        cbbPath.setVisible(false);
        divError.setVisible(false);

        btnReaddingFile.setVisible(false);
    }

    private void initialCombobox() {

        File file = new File(FileAttribute.SETTING_TAG_HOTFIX_FILE);
        LOG.info(file.getAbsolutePath());

        if (!file.exists()) {
            FileUtil.createFile(FileAttribute.SETTING_TAG_HOTFIX_FILE, new StringBuilder(""));
        }

        generateSettingFile();

        Collections.reverse(path);
        ComboboxUtil.buildCombobox(cbbPath, path, cbbPath.getText());

        Collections.reverse(tagName);
        ComboboxUtil.buildCombobox(cbbTagName, tagName, cbbTagName.getText());

        Collections.reverse(header);
        ComboboxUtil.buildCombobox(cbbHeader, header, cbbHeader.getText());

        Collections.reverse(cvsName);
        ComboboxUtil.buildCombobox(cbbCVSName, cvsName, cbbCVSName.getText());

        Collections.reverse(lastedTagName);
        ComboboxUtil.buildCombobox(cbbLastedTagName, lastedTagName, cbbLastedTagName.getText());
    }

    private void initialEventListener() {
        rdoType.addEventListener(Events.ON_CHECK, new ChooseType());
        btnGenerate.addEventListener(Events.ON_CLICK, new GenerateTagScript());
        btnReaddingFile.addEventListener(Events.ON_CLICK, new ReaddingTextFile());
        btnUpload.addEventListener(Events.ON_UPLOAD, new UploadExcelFile());
    }

    private class ChooseType implements EventListener {

        @Override
        public void onEvent(Event t) throws Exception {
            if (rdoType.getSelectedIndex() == 0) {
                cbbPath.setVisible(false);
                btnUpload.setVisible(true);
                mainLabel.setValue("Upload");
                btnReaddingFile.setVisible(false);
            } else if (rdoType.getSelectedIndex() == 1) {
                cbbPath.setVisible(true);
                btnUpload.setVisible(false);
                mainLabel.setValue("Path");
                btnReaddingFile.setVisible(true);
            }
        }
    }

    private class ReaddingTextFile implements EventListener {

        @Override
        public void onEvent(Event t) throws Exception {
            if (!validateFile()) {
                return;
            }

            appendSettingFile();

            List<Tag> tagList = GenScript.generate(cbbPath.getText());

            List<Tag> listNormal = new ArrayList<Tag>();
            List<Tag> listDiff = new ArrayList<Tag>();
            List<Tag> listError = new ArrayList<Tag>();
            List<Tag> listDel = new ArrayList<Tag>();
            List<Tag> listReversionDel = new ArrayList<Tag>();
            List<Integer> listPosDel = new ArrayList<Integer>();
            List<Integer> listPosAdd = new ArrayList<Integer>();
            List<Integer> listPosChangeReversion = new ArrayList<Integer>();

            for (Tag tag : tagList) {
                
                tag.setIssue("DONE-1363");
                User user = new User();
                user.setUsername("pattana");
                tag.setUser(user);

                StringBuilder sb = new StringBuilder();
                sb.append("cvs log ").append(tag.getPath());

                LOG.info(":::::::::::::::::::::::: sb = " + sb.toString());

                ProcessUbuntu process = new ProcessUbuntu(cbbHeader.getText(), sb);
                process.process("chmod 777 " + cbbHeader.getText() + "/" + ProcessUbuntu.TEMP_SCRIPT_FILENAME);
                process.process();

                if (!StringUtils.isEmpty(process.getErrorString())) {
                    tag.setDescription("Path ผิด");
                    listError.add(tag);
                } else {
                    String[] logTag = process.getOutputString().split("\n");
                    Boolean isSuccess = validateTag(logTag, cbbLastedTagName.getText().trim(),
                            tag);

                    if (isSuccess) {
                        listNormal.add(tag);
                    } else {
                        listError.add(tag);
                    }
                }
            }

            for (Tag o1 : listNormal) {
                for (Tag o2 : listNormal) {
                    if (o1.getIssue().equalsIgnoreCase(o2.getIssue())
                            && o1.getPath().equalsIgnoreCase(o2.getPath())
                            && !o1.getRevision().equalsIgnoreCase(o2.getRevision())) {

                        boolean isDelDuplicate = false;
                        for (int n : listPosDel) {
                            if (n == listNormal.indexOf(o2)) {
                                isDelDuplicate = true;
                                break;
                            }

                        }

                        for (int n2 : listPosChangeReversion) {
                            if (n2 == listNormal.indexOf(o2)) {
                                isDelDuplicate = true;
                                break;
                            }
                        }

                        String reversion = containReversion(o1.getRevision(), o2.getRevision(), Boolean.FALSE);
                        if (!isDelDuplicate && reversion != null) {
                            o1.setRevision(reversion);
                            listPosChangeReversion.add(listNormal.indexOf(o1));
                            listReversionDel.add(o2);
                            listPosDel.add(listNormal.indexOf(o2));
                        }
                    } else if (!o1.getIssue().equalsIgnoreCase(o2.getIssue())
                            && o1.getPath().equalsIgnoreCase(o2.getPath())
                            && !o1.getRevision().equalsIgnoreCase(o2.getRevision())) {
                        boolean isDelDuplicate = false;
                        boolean isAddDuplicate = false;
                        for (int n : listPosDel) {
                            if (n == listNormal.indexOf(o2)) {
                                isDelDuplicate = true;
                                break;
                            }
                        }
                        for (int n : listPosAdd) {
                            if (n == listNormal.indexOf(o2)) {
                                isAddDuplicate = true;
                                break;
                            }
                        }
                        if (!isDelDuplicate) {
                            listDel.add(o2);
                            listPosDel.add(listNormal.indexOf(o2));
                        }
                        if (!isAddDuplicate) {
                            listPosAdd.add(listNormal.indexOf(o2));
                        }
                    }
                }
            }

            for (int pos : listPosAdd) {
                LOG.info(":::::::::::::::::: posAdd = " + pos);
                listDiff.add(listNormal.get(pos));
            }
            for (int pos : listPosDel) {
                LOG.info(":::::::::::::::::: posDel = " + pos);
            }

            LOG.info(":::::::::::::::::::: listNormal.size() = " + listNormal.size());

            listNormal.removeAll(listDel);
            listNormal.removeAll(listReversionDel);
            listDiff.removeAll(listReversionDel);

            Collections.sort(listNormal, new Comparator<Tag>() {
                @Override
                public int compare(Tag o1, Tag o2) {
                    return o1.getPath().compareTo(o2.getPath());
                }
            });
            normalRender = new TagHotfixNormalMainRenderer(chkAll);
            generateRenderer(gridTagNormal, normalRender, listNormal);

            Collections.sort(listDiff, new Comparator<Tag>() {
                @Override
                public int compare(Tag o1, Tag o2) {
                    return o1.getPath().compareTo(o2.getPath());
                }
            });
            diffRender = new TagHotfixDiffMainRenderer();
            generateRenderer(gridDiffTag, diffRender, listDiff);

            errorRender = new TagHotfixErrorMainRenderer();
            generateRenderer(gridErrorTag, errorRender, listError);

            if (listError.size() > 0) {
                divError.setVisible(true);
            } else {
                divError.setVisible(false);
            }

            lbTotalNormal.setValue(String.valueOf(listNormal.size()));
            lbTotalDifference.setValue(String.valueOf(listDiff.size()));
            lbTotalError.setValue(String.valueOf(listError.size()));

//            normalRender = new TagHotfixNormalMainRenderer(chkAll);
//            generateRenderer(gridTagNormal, normalRender, tag);
//
//            diffRender = new TagHotfixDiffMainRenderer();
//            generateRenderer(gridDiffTag, diffRender, new ArrayList<Tag>());
        }
    }

    private class GenerateTagScript implements EventListener {

        @Override
        public void onEvent(Event event) throws Exception {
            String filename = cbbHeader.getText() + "/" + ProcessUbuntu.TEMP_SCRIPT_FILENAME;

            if (!validate()) {
                return;
            }

            List<Tag> listTag = new ArrayList<Tag>();
            for (Object o : normalRender.selectTemplateList) {
                Tag tag = (Tag) o;
                listTag.add(tag);
            }
            for (Object o : diffRender.getObjectSelect()) {
                Tag tag = (Tag) o;
                listTag.add(tag);
            }
            GenerateScriptUtil.generate(listTag, cbbTagName.getText(), cbbCVSName.getText(), filename);

            List<String> script = TextFileReaderUtil.read(filename);
            LOG.info("::::::::::::::::::::::::: script.size() = " + script.size());

            Map map = new HashMap<String, Object>();
            map.put(PopupCtrl.EXECUTION_SCRIPT, script);
            map.put(PopupCtrl.EXECUTION_SCRIPT_FILENAME, filename);
            map.put(PopupCtrl.EXECUTION_SCRIPT_FILEPATH, cbbHeader.getText());
            Component comp = Executions.createComponents(FROM_POPUP_TEMPLATE, null, map);

            if (comp instanceof Window) {
                Window win = (Window) comp;
                win.setTitle(ProcessUbuntu.TEMP_SCRIPT_FILENAME);
                win.setPosition("0");
                win.doModal();
            }
        }
    }

    private class UploadExcelFile implements EventListener {

        public UploadExcelFile() {
        }

        @Override
        public void onEvent(Event t) throws Exception {

            if (StringUtils.isEmpty(cbbLastedTagName.getText())) {
                alert("Please full fill on Lasted Tag Name.");
                return;
            }

            appendSettingFile();

            UploadEvent upload = (UploadEvent) t;
            Media media = upload.getMedia();
            LOG.info(media.getContentType());

            LOG.info(media.getStreamData());

            List<String[]> reading = ImportFileReaderUtil.readXlsxExcelDataList(media.getStreamData(), 6, true);
            List<Tag> listNormal = new ArrayList<Tag>();
            List<Tag> listDiff = new ArrayList<Tag>();
            List<Tag> listError = new ArrayList<Tag>();
            List<Tag> listDel = new ArrayList<Tag>();
            List<Tag> listReversionDel = new ArrayList<Tag>();
            List<Integer> listPosDel = new ArrayList<Integer>();
            List<Integer> listPosAdd = new ArrayList<Integer>();
            List<Integer> listPosChangeReversion = new ArrayList<Integer>();

            for (String[] s : reading) {
                String[] filename = s[3].split("/");

                Tag tag = new Tag();
                tag.setIssue(s[0].trim());
//                tag.setAuthor(s[1].trim().toLowerCase());
                tag.setRevision(s[2].trim());
                tag.setPath(s[3].trim());
                tag.setFilename(filename[filename.length - 1].trim());
                tag.setDescription(s[4].trim());
//                tag.setDate(s[5].trim());

                StringBuilder sb = new StringBuilder();
                sb.append("cvs log ").append(tag.getPath());

                LOG.info(":::::::::::::::::::::::: sb = " + sb.toString());

                ProcessUbuntu process = new ProcessUbuntu(cbbHeader.getText(), sb);
                process.process("chmod 777 " + cbbHeader.getText() + "/" + ProcessUbuntu.TEMP_SCRIPT_FILENAME);
                process.process();

                if (!StringUtils.isEmpty(process.getErrorString())) {
                    tag.setDescription("Path ผิด");
                    listError.add(tag);
                } else {
                    String[] logTag = process.getOutputString().split("\n");
                    Boolean isSuccess = validateTag(logTag, cbbLastedTagName.getText().trim(),
                            tag);

                    if (isSuccess) {
                        listNormal.add(tag);
                    } else {
                        listError.add(tag);
                    }
                }
            }

            for (Tag o1 : listNormal) {
                for (Tag o2 : listNormal) {
                    if (o1.getIssue().equalsIgnoreCase(o2.getIssue())
                            && o1.getPath().equalsIgnoreCase(o2.getPath())
                            && !o1.getRevision().equalsIgnoreCase(o2.getRevision())) {

                        boolean isDelDuplicate = false;
                        for (int n : listPosDel) {
                            if (n == listNormal.indexOf(o2)) {
                                isDelDuplicate = true;
                                break;
                            }

                        }

                        for (int n2 : listPosChangeReversion) {
                            if (n2 == listNormal.indexOf(o2)) {
                                isDelDuplicate = true;
                                break;
                            }
                        }

                        String reversion = containReversion(o1.getRevision(), o2.getRevision(), Boolean.FALSE);
                        if (!isDelDuplicate && reversion != null) {
                            o1.setRevision(reversion);
                            listPosChangeReversion.add(listNormal.indexOf(o1));
                            listReversionDel.add(o2);
                            listPosDel.add(listNormal.indexOf(o2));
                        }
                    } else if (!o1.getIssue().equalsIgnoreCase(o2.getIssue())
                            && o1.getPath().equalsIgnoreCase(o2.getPath())
                            && !o1.getRevision().equalsIgnoreCase(o2.getRevision())) {
                        boolean isDelDuplicate = false;
                        boolean isAddDuplicate = false;
                        for (int n : listPosDel) {
                            if (n == listNormal.indexOf(o2)) {
                                isDelDuplicate = true;
                                break;
                            }
                        }
                        for (int n : listPosAdd) {
                            if (n == listNormal.indexOf(o2)) {
                                isAddDuplicate = true;
                                break;
                            }
                        }
                        if (!isDelDuplicate) {
                            listDel.add(o2);
                            listPosDel.add(listNormal.indexOf(o2));
                        }
                        if (!isAddDuplicate) {
                            listPosAdd.add(listNormal.indexOf(o2));
                        }
                    }
                }
            }

            for (int pos : listPosAdd) {
                LOG.info(":::::::::::::::::: posAdd = " + pos);
                listDiff.add(listNormal.get(pos));
            }
            for (int pos : listPosDel) {
                LOG.info(":::::::::::::::::: posDel = " + pos);
            }

            LOG.info(":::::::::::::::::::: listNormal.size() = " + listNormal.size());

            listNormal.removeAll(listDel);
            listNormal.removeAll(listReversionDel);
            listDiff.removeAll(listReversionDel);

            Collections.sort(listNormal, new Comparator<Tag>() {
                @Override
                public int compare(Tag o1, Tag o2) {
                    return o1.getPath().compareTo(o2.getPath());
                }
            });
            normalRender = new TagHotfixNormalMainRenderer(chkAll);
            generateRenderer(gridTagNormal, normalRender, listNormal);

            Collections.sort(listDiff, new Comparator<Tag>() {
                @Override
                public int compare(Tag o1, Tag o2) {
                    return o1.getPath().compareTo(o2.getPath());
                }
            });
            diffRender = new TagHotfixDiffMainRenderer();
            generateRenderer(gridDiffTag, diffRender, listDiff);

            errorRender = new TagHotfixErrorMainRenderer();
            generateRenderer(gridErrorTag, errorRender, listError);

            if (listError.size() > 0) {
                divError.setVisible(true);
            } else {
                divError.setVisible(false);
            }

            FileUtil.uploadExcel(media.getStreamData(), media.getName());

            lbTotalNormal.setValue(String.valueOf(listNormal.size()));
            lbTotalDifference.setValue(String.valueOf(listDiff.size()));
            lbTotalError.setValue(String.valueOf(listError.size()));
        }
    }

    private void generateRenderer(Grid grid, RowRenderer renderer, List model) {
        grid.setRowRenderer(renderer);
        grid.setModel(new ListModelList<Tag>(model));
    }

    private String containReversion(String o1, String o2, Boolean isMore) {

        String[] reversion1 = o1.replace(".", ",").split(",");
        String[] reversion2 = o2.replace(".", ",").split(",");

        if (reversion1.length != reversion2.length) {
            return null;
        }

        LOG.info("::::::::::::::::::: reversion1.length = " + Arrays.toString(reversion1));
        LOG.info("::::::::::::::::::: reversion1.length = " + Arrays.toString(reversion2));

        for (int i = 0; i < reversion1.length; i++) {
            Integer num1 = Integer.parseInt(reversion1[i]);
            Integer num2 = Integer.parseInt(reversion2[i]);

            LOG.info("::::::::::::::::::: num1 [" + i + "] = " + num1);
            LOG.info("::::::::::::::::::: num2 [" + i + "] = " + num2);

            if (isMore) {
                if (num1 > num2) {
                    return o1;
                }
                if (num1 < num2) {
                    return o2;
                }
            } else {

                if (num1 - 1 == num2) {
                    return o1;
                }
                if (num2 - 1 == num1) {
                    return o2;
                }
            }
        }
        return null;
    }

    private void generateSettingFile() {
        List<String> allSetting = TextFileReaderUtil.read(FileAttribute.SETTING_TAG_HOTFIX_FILE);
        path = new ArrayList<String>();
        tagName = new ArrayList<String>();
        header = new ArrayList<String>();
        cvsName = new ArrayList<String>();
        lastedTagName = new ArrayList<String>();

        if (!allSetting.isEmpty()) {
            for (String s : allSetting) {
                String[] setting = s.trim().split("=");
                if (setting[0].equals("PATH")) {
                    path.add(setting[1]);
                } else if (setting[0].equals("TAG_NAME")) {
                    tagName.add(setting[1]);
                } else if (setting[0].equals("HEADER")) {
                    header.add(setting[1]);
                } else if (setting[0].equals("CVS_NAME")) {
                    cvsName.add(setting[1]);
                } else if (setting[0].equals("LASTED_TAG_NAME")) {
                    lastedTagName.add(setting[1]);
                }
            }
        }
    }

    private void appendSettingFile() {
        if (!path.contains(cbbPath.getText())
                && !StringUtils.isEmpty(cbbPath.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_HOTFIX_FILE, "PATH=" + cbbPath.getText().trim());
        }
        System.out.println("path = " + path.contains(cbbPath.getText()));
        System.out.println("cbbPath = " + cbbPath.getText());

        if (!tagName.contains(cbbTagName.getText())
                && !StringUtils.isEmpty(cbbTagName.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_HOTFIX_FILE, "TAG_NAME=" + (cbbTagName.getText()));
        }
        System.out.println("tagName = " + tagName.contains(cbbTagName.getText()));
        System.out.println("cbbTagName = " + cbbTagName.getText());

        if (!header.contains(cbbHeader.getText())
                && !StringUtils.isEmpty(cbbHeader.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_HOTFIX_FILE, "HEADER=" + (cbbHeader.getText()).trim());
        }
        System.out.println("header = " + header.contains(cbbHeader.getText()));
        System.out.println("cbbHeader = " + cbbHeader.getText());

        if (!cvsName.contains(cbbCVSName.getText())
                && !StringUtils.isEmpty(cbbCVSName.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_HOTFIX_FILE, "CVS_NAME=" + cbbCVSName.getText());
        }
        System.out.println("cvsName = " + cvsName.contains(cbbCVSName.getText()));
        System.out.println("cbbCVSName = " + cbbCVSName.getText());

        if (!lastedTagName.contains(cbbLastedTagName.getText())
                && !StringUtils.isEmpty(cbbLastedTagName.getText())) {
            FileUtil.appandText(FileAttribute.SETTING_TAG_HOTFIX_FILE, "LASTED_TAG_NAME=" + cbbLastedTagName.getText());
        }
        System.out.println("lastedTagName = " + lastedTagName.contains(cbbLastedTagName.getText()));
        System.out.println("cbbCVSName = " + cbbLastedTagName.getText());

        initialCombobox();
    }

    private Boolean validateTag(String[] tag,
            String inputResolveTagName,
            Tag tagObject) {

        String inputRevision = tagObject.getRevision();
        String inputIssue = tagObject.getIssue();
        String inputAuthor = tagObject.getUser().getUsername();

        if (tag == null || inputResolveTagName == null || inputIssue == null || inputAuthor == null || inputRevision == null) {
            tagObject.setDescription("ข้อมูลบางอย่างหายไป");
            return Boolean.FALSE;
        }

        String resolveVersion = null;
        String revision = null;
        String issue = null;
        String author = null;
        int idx = 0;
        for (String s : tag) {
            if (s.length() > 12) {
                if (revision != null
                        && resolveVersion != null) {
                    break;
                }
                if (s.substring(0, 8).equals("revision")
                        && revision == null
                        && s.substring(9, s.length()).replace(".", ",").split(",").length == 4) {
                    revision = s.substring(9, s.length());
                    author = tag[idx + 1].substring(tag[idx + 1].indexOf("author: ") + "author: ".length(),
                            tag[idx + 1].indexOf("state:") - 3);
                    issue = tag[idx + 2];
                }
                if (s.indexOf(inputResolveTagName + ":") == 1
                        && resolveVersion == null) {
                    resolveVersion = s.substring((inputResolveTagName + ": ").length(), s.length());
                }
            }
            ++idx;
        }

        LOG.info("::::::::::::: resolveVersion = " + resolveVersion);
        LOG.info("::::::::::::: revision = " + revision);
        LOG.info("::::::::::::: author = " + author);
        LOG.info("::::::::::::: issue = " + issue);

        tagObject.setVersion(resolveVersion == null ? "New File" : resolveVersion);

        if (issue == null || author == null || revision == null) {
            return Boolean.FALSE;
        }

        revision = revision.trim();
        issue = issue.trim();
        author = author.trim();

//        if (!inputIssue.trim().equals(issue.trim())) {
//            tagObject.setDescription("Issue ที่ Commit ไม่ตรงกับ Issue ส่งไฟล์มา");
//            return Boolean.FALSE;
//        }

        if (!author.trim().equals(inputAuthor.trim())) {
            tagObject.setDescription("คนที่ Commit ไม่ตรงกับคนที่ส่งไฟล์มา");
            return Boolean.FALSE;
        }

        if (resolveVersion != null
                && containReversion(inputRevision, resolveVersion.trim(), Boolean.FALSE) == null) {

            Boolean isNow = Boolean.FALSE;
            Boolean isValidate = Boolean.TRUE;
            Boolean isEnd = Boolean.FALSE;
            String authorValidate = "";
            String revisionValidate = "";
            while (!isEnd) {
                StringBuilder sb = new StringBuilder();
                sb.append("cvs log ").append(tagObject.getPath());

                LOG.info(":::::::::::::::::::::::: sb = " + sb.toString());

                ProcessUbuntu process = new ProcessUbuntu(cbbHeader.getText(), sb);
                process.process("chmod 777 " + cbbHeader.getText() + "/" + ProcessUbuntu.TEMP_SCRIPT_FILENAME);
                process.process();

                String[] tagValidate = process.getOutputString().split("\n");
                idx = 0;
                for (String s : tagValidate) {
                    if (s.length() > 12) {
                        if (s.substring(0, 8).equals("revision")
                                && s.substring(9, s.length()).trim().equals(inputRevision.trim())) {
                            isNow = Boolean.TRUE;
                        }
                        if (s.substring(0, 8).equals("revision")
                                && isNow) {
                            authorValidate = tagValidate[idx + 1].substring(tagValidate[idx + 1].indexOf("author: ") + "author: ".length(),
                                    tagValidate[idx + 1].indexOf("state:") - 3);

                            revisionValidate = s.substring(9, s.length()).trim();

                            LOG.info("::::::::::::::::::::::: authorValidate = " + authorValidate);
                            LOG.info("::::::::::::::::::::::: revisionValidate = " + revisionValidate);

                            if (!authorValidate.trim().equals(tagObject.getUser().getUsername().trim())) {
                                isValidate = Boolean.FALSE;
                                isEnd = Boolean.TRUE;
                                break;
                            }

                            if (revisionValidate.equals(resolveVersion.trim())) {
                                isEnd = Boolean.TRUE;
                                break;
                            }
                        }
                    }
                    ++idx;
                }
            }

            if (!isValidate) {
                tagObject.setDescription("Version กระโดด ณ version ที่ " + revisionValidate + " ผู้ commit คือ " + authorValidate + " กรุณาตรวจสอบ");
                return Boolean.FALSE;
            }
        }

        if (resolveVersion != null
                && resolveVersion.trim().equals(containReversion(inputRevision, resolveVersion.trim(), Boolean.TRUE))) {
            tagObject.setDescription("Version ไม่ถูกต้อง กรุณาตรวจสอบ");
            return Boolean.FALSE;
        }

        if (inputRevision.equals(containReversion(inputRevision, revision, Boolean.TRUE))) {
            tagObject.setDescription("Version ไม่ถูกต้อง กรุณาตรวจสอบ");
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    private Boolean validateFile() {
        if (StringUtils.isEmpty(cbbPath.getText())) {
            alert("Please input path fill.");
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }

    private Boolean validate() {

        if (StringUtils.isEmpty(cbbTagName.getText())
                || StringUtils.isEmpty(cbbHeader.getText())
                || StringUtils.isEmpty(cbbCVSName.getText())
                || StringUtils.isEmpty(cbbLastedTagName.getText())) {
            alert("Please full every fill.");
            return Boolean.FALSE;
        }

        if (errorRender.getRowRenderer().size() > 0) {
            alert("Please check error tag.");
            return Boolean.FALSE;
        }

        return Boolean.TRUE;
    }
}
